package com.jonluo.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.*;

/**
 * Created by 钜文 on 2017/4/25.
 */
@Controller
@RequestMapping({"/doc"})
public class DocLoadController {

    @Value("${files-server-url}")
    private String UPLOAD_URL;

    public DocLoadController() {
    }

    /**
     *
     * @param request 参数
     * type："file" 文件 "photo" 图片
     * more： 数字，最多上传多少个文件
     * uploadAction： true 能上传 false不能上传
     * filenames：文件名字符串，多个以逗号隔开
     *
     * @return
     */
    @RequestMapping(value = {"/index"}, produces = {"text/html; charset=utf-8"})
    @ResponseBody
    public String index(HttpServletRequest request, HttpServletResponse response, Model model) {
        String returnStr = "";
        try {
            Map<String, String> maps = new HashMap();
            Set set = request.getParameterMap().entrySet();
            Iterator it = set.iterator();
            while (it.hasNext()) {
                Map.Entry entry = (Map.Entry) it.next();
                String[] tmp = (String[]) entry.getValue();
                for (int i = 0; i < tmp.length; i++) {
                    maps.put(String.valueOf(entry.getKey()), tmp[i]);
                }
            }
            returnStr = post(UPLOAD_URL + "/fileUploader/index", maps, null, request);
        } catch (Exception e) {
            e.printStackTrace();
            returnStr = "控件加载失败";
        }
        return returnStr;
    }


    @RequestMapping(value = {"/uploadFile"}, produces = {"text/plain; charset=utf-8"})
    @ResponseBody
    public String uploadFile(HttpServletRequest request, HttpServletResponse response, @RequestParam MultipartFile file) {

        String returnStr = "";
        try {
            Map<String, InputStream> files = new HashMap();
            files.put(file.getOriginalFilename(), file.getInputStream());
            Map<String, String> maps = new HashMap();
            Set set = request.getParameterMap().entrySet();
            Iterator it = set.iterator();
            while (it.hasNext()) {
                Map.Entry entry = (Map.Entry) it.next();
                String[] tmp = (String[]) entry.getValue();
                for (int i = 0; i < tmp.length; i++) {
                    maps.put(String.valueOf(entry.getKey()), tmp[i]);
                }
            }
            returnStr = post(UPLOAD_URL + "/fileUploader/upload", maps, files, request);
        } catch (Exception e) {
            e.printStackTrace();
            returnStr = "error";
        }
        return returnStr;
    }


    private static String post(String actionUrl, Map<String, String> params, Map<String, InputStream> files, HttpServletRequest request)
            throws IOException {
        String BOUNDARY = UUID.randomUUID().toString();
        String PREFIX = "--";
        String LINEND = "\r\n";
        String MULTIPART_FROM_DATA = "multipart/form-data";
        String CHARSET = "UTF-8";

        URL uri = new URL(actionUrl);
        HttpURLConnection conn = (HttpURLConnection) uri.openConnection();
        conn.setReadTimeout(10000);
        conn.setDoInput(true);
        conn.setDoOutput(true);
        conn.setUseCaches(false);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Referer", request.getHeader("Referer"));
        conn.setRequestProperty("Origin", request.getHeader("Origin"));
        conn.setRequestProperty("connection", "keep-alive");
        conn.setRequestProperty("Charsert", CHARSET);
        conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA + ";boundary=" + BOUNDARY);

        DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());
        if (params != null) {
            StringBuilder sb = new StringBuilder();
            for (Map.Entry<String, String> entry : params.entrySet()) {
                sb.append(PREFIX);
                sb.append(BOUNDARY);
                sb.append(LINEND);
                sb.append("Content-Disposition: form-data; name=\"" + (String) entry.getKey() + "\"" + LINEND);
                sb.append("Content-Type: text/plain; charset=" + CHARSET + LINEND);
                sb.append("Content-Transfer-Encoding: 8bit" + LINEND);
                sb.append(LINEND);
                sb.append((String) entry.getValue());
                sb.append(LINEND);
            }
            outStream.write(sb.toString().getBytes());
        }


        StringBuilder sb2 = null;

        if (files != null) {
            for (Map.Entry<String, InputStream> file : files.entrySet()) {
                String fileName = URLEncoder.encode((String) file.getKey(), "UTF-8");
                StringBuilder sb1 = new StringBuilder();
                sb1.append(PREFIX);
                sb1.append(BOUNDARY);
                sb1.append(LINEND);
                sb1.append("Content-Disposition: form-data; name=\"file\"; filename=\"" + fileName + "\"" + LINEND);
                sb1.append("Content-Type: application/octet-stream; charset=" + CHARSET + LINEND);
                sb1.append(LINEND);
                outStream.write(sb1.toString().getBytes());
                InputStream is = (InputStream) file.getValue();
                byte[] buffer = new byte['?'];
                int len = 0;
                while ((len = is.read(buffer)) != -1) {
                    outStream.write(buffer, 0, len);
                }
                is.close();
                outStream.write(LINEND.getBytes());
            }
        }

        byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();
        outStream.write(end_data);
        outStream.flush();

        int res = conn.getResponseCode();
        if (res == 200) {
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
            sb2 = new StringBuilder();
            int ch;
            while ((ch = br.read()) != -1) {
                sb2.append((char) ch);
            }
        }
        outStream.close();
        conn.disconnect();
        return sb2.toString();
    }


    @RequestMapping("/delete/{filename:.+}")
    @ResponseBody
    public String delete(@PathVariable String filename, Model model, HttpServletResponse response, HttpServletRequest request) {

        String returnStr = "";
        try {
            returnStr = post(UPLOAD_URL + "/fileUploader/deleteFile/" + filename, null, null, request);
        } catch (Exception e) {
            e.printStackTrace();
            returnStr = "error";
        }
        return returnStr;
    }

    @RequestMapping(value = {"/files/{filename:.+}"})
    @ResponseBody
    public ResponseEntity<Resource> serveFile(@PathVariable String filename) {
        RestTemplate restTemplate = new RestTemplate();
        Resource file  =restTemplate.getForEntity(UPLOAD_URL+ "/fileUploader/files/"+filename, Resource.class).getBody();
        return ResponseEntity.ok(file);
    }

}
